#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/stat.h>

#include "configuration.h"
#include "color.h"
#include "leaderboard.h"
#include "homepage.h"

/**
 * @brief   初始化登陆信息
 * @param   void
 * @return  错误返回-ERROR 失败返回FALSE 成功返回TRUE
 */
int leaderboard_init(void)
{
    struct board player;
    FILE *fp = NULL;

    if (access(LIB_DIR, F_OK) != 0)
        mkdir(LIB_DIR, 0777);

    memset(&player.name, 0, sizeof(player.name));

    //判断文件是否可以正确创建/打开
    if (!(fp = fopen(GUESS_FILE_PATH, "a+")) || 
        !(fp = fopen(CLICK_FILE_PATH, "a+")) ) {
        perror(GUESS_FILE_PATH);
        perror(CLICK_FILE_PATH);
        return FALSE;
    }
    if (!fp) {
        printf("open file false");
        return -ERROR;
    }
    if (!(fp = fopen(PLAYER_NAME_PATH, "ab+")) ) {
        perror(PLAYER_NAME_PATH);
        exit(EXIT_FAILURE);
    }
    if (fscanf(fp, "init\t\n") == EOF) {
        fprintf(fp, "init\t\n");
        fflush(fp);
        rewind(fp);
    }
    fclose(fp);
    
    return TRUE;
}

/**
 * @brief   用户名称登记
 * @param   void
 * @return  void
 */
void player_name(void)
{
    struct board player, input;
    int length = 0;
    int temp = 0;
    int sign = 0;
    FILE *fp = NULL;

    memset(&player, '\0', sizeof(struct board));
    memset(&input, '\0', sizeof(struct board));

    while(TRUE) {
        printf(YELLOW
                "\n\n==================================="
                "  \n==================================="
                "\n\n* Please ENTER you PLAYER NAME: "
                NONE);
        scanf("%s", input.name);
        length = strlen(input.name);

        sign = 0;
        for (temp=0; temp<length; temp++) {
            if (length > NAME_LENGTH
                || input.name[temp] < '0' 
                || (input.name[temp] > '9' && input.name[temp] < 'A') 
                || (input.name[temp] > 'Z' && input.name[temp] < 'a') 
                || input.name[temp] > 'z') {
                printf("You should enter 7 English or Number name!\n");
                sign = -ERROR;
            }
            else
                sign = TRUE;
                break;
        }
        if (sign == TRUE)
            break;
        else if (sign == -ERROR)
            continue;
        else
            printf(L_RED "PLAYER NAME error!\n" NONE);
    }

    /**
     * 1.判断用户名是否存在
     * 2.打开相应的文件读写信息
     */
    sign = 0;
    if (!(fp = fopen(PLAYER_NAME_PATH, "ab+")) ) {
        perror(PLAYER_NAME_PATH);
        exit(EXIT_FAILURE);
    }
    while (fscanf(fp, "%s\t\n", player.name) != EOF) {

        if ( !strcmp(player.name, input.name) ) {
            sign = TRUE;
            break;
        } else {
            sign = -1;
        }        
    }

    if (sign == TRUE) {
        system("clear");
        printf(YELLOW "\t\tWELCOME! %s!!!\n\n" NONE, player.name);
    } else if (sign == -1) {
        strcpy(player.name, input.name);

        if (!(fp = fopen(PLAYER_NAME_PATH, "ab+")) ) {
            perror(PLAYER_NAME_PATH);
            exit(EXIT_FAILURE);
        }
        fprintf(fp, "%s\t\n", player.name);
        fflush(fp);
        rewind(fp);
        
        if (!(fp = fopen(CLICK_FILE_PATH, "ab+")) ) {
            perror(CLICK_FILE_PATH);
            exit(EXIT_FAILURE);
        }
        fprintf(fp, "%s\t", player.name);
        fflush(fp);
        rewind(fp);

        if (!(fp = fopen(GUESS_FILE_PATH, "ab+")) ) {
            perror(GUESS_FILE_PATH);
            exit(EXIT_FAILURE);
        }
        fprintf(fp, "%s\t", player.name);
        fflush(fp);
        rewind(fp);
        fclose(fp);
    }

    system("clear");
    printf(YELLOW "\t\tWELCOME! %s!!!\n\n" NONE, player.name);
}

/**
 * @brief   获取猜数字游戏分数并保存写入GUESS_FILE_PATH
 * @param   (int score)
 * @return  void
 */
void guess_score_get(int score)
{
    struct board player, old;
    old.guess_score = 0;
    player.guess_score = 0;

    memset(&player, 0, sizeof(player));
    memset(&old, 0, sizeof(old));
    FILE *fp = NULL;

    if ( !(fp = fopen(GUESS_FILE_PATH, "r+")) ) {
        perror(GUESS_FILE_PATH);
        exit(EXIT_FAILURE);
    }    
    
    fseek(fp, 0, SEEK_SET);
    while (fscanf(fp, "%s\t", old.name) != EOF) {

        if (strcmp(old.name, player.name) == 0) {
            player.guess_score = score;
            fprintf(fp, "%s\t%d\n", player.name, player.guess_score);
            fflush(fp);
            rewind(fp);
            break;
        }

        if (strcmp(old.name, player.name) != 0) {
            if (old.guess_score == 0 || old.guess_score > player.guess_score)
                player.guess_score = score;

            fprintf(fp, "%s\t%d\n", player.name, player.guess_score);
            fflush(fp);
            rewind(fp);
            //continue;
            break;
        }
    }

    fclose(fp);
}

/**
 * @brief   从GUESS_FILE_PATH获取猜数字游戏分数并输出屏幕
 * @param   void
 * @return  void
 */
void guess_board_put(void)
{
    struct board player;
    player.guess_score = 0;
    int ranking = 0;
    
    FILE *fp = NULL;

    if ( !(fp = fopen(GUESS_FILE_PATH, "a+")) ) {
        perror(GUESS_FILE_PATH);
        exit(EXIT_FAILURE);
    }
    printf(L_CYAN "====== GUESS LeaderBoard ======\n\n" NONE);
    printf(L_CYAN "RANKING\tNAME\t\tSCORE\n\n" NONE);

    while (fscanf(fp, "%s\t%d\n", player.name, &player.guess_score) != EOF) {
        
        ranking++;
        printf(L_CYAN "%d\t%s\t\t%d\n" NONE,ranking, player.name, player.guess_score);
    }

    fclose(fp);
}

/**
 * @brief   获取疯狂点击游戏分数并保存写入CLICK_FILE_PATH
 * @param   (int score)
 * @return  void
 */
void click_score_get(int score)
{
    struct board player, old;
    old.click_score = 0;
    player.click_score = 0;

    memset(&player, 0, sizeof(player));
    memset(&old, 0, sizeof(old));
    FILE *fp = NULL;

    if ( !(fp = fopen(CLICK_FILE_PATH, "r+")) ) {
        perror(CLICK_FILE_PATH);
        exit(EXIT_FAILURE);
    }    
    
    fseek(fp, 0, SEEK_SET);
    while (fscanf(fp, "%s\t", old.name) != EOF) {

        if (strcmp(old.name, player.name) == 0) {
            player.click_score = score;
            fprintf(fp, "%s\t%d\n", player.name, player.click_score);
            fflush(fp);
            rewind(fp);
            break;
        }

        if (strcmp(old.name, player.name) != 0) {
            if (old.click_score == 0 || old.click_score < player.click_score)
                player.click_score = score;

            fprintf(fp, "%s\t%d\n", player.name, player.click_score);
            fflush(fp);
            rewind(fp);
            break;
        }
    }

    fclose(fp);
}

/**
 * @brief   从CLICK_FILE_PATH获取猜数字游戏分数并输出屏幕
 * @param   void
 * @return  void
 */
void click_board_put(void)
{
    struct board player;
    player.click_score = 0;
    int ranking = 0;    
    FILE *fp = NULL;

    if ( !(fp = fopen(CLICK_FILE_PATH, "a+")) ) {
        perror(CLICK_FILE_PATH);
        exit(EXIT_FAILURE);
    }
    printf(L_CYAN "====== CLICK LeaderBoard ======\n\n" NONE);
    printf(L_CYAN "RANKING\tNAME\t\tSCORE\n\n" NONE);

    while (fscanf(fp, "%s\t%d\n", player.name, &player.click_score) != EOF) {
        
        ranking++;
        printf(L_CYAN "%d\t%s\t\t%d\n" NONE,ranking, player.name, player.click_score);
    }

    fclose(fp);
}

/**
 * @brief   主菜单排行榜显示
 * @param   void
 * @return  void
 */
void main_board(void)
{
    char main_input[10];

    click_board_put();
    putchar('\n');
    guess_board_put();

    printf(YELLOW "\n\nEnter 'r' to main menu:\n" NONE);
    while (1) {
        set_buffered_input(false);
        main_input[0] = getchar();
        set_buffered_input(true);

        if (main_input[0] != EOF && main_input[0] == 'r') {
            system("clear");
            show_main_menu();
            choice_main_menu();
        } else
            continue;
    }
}
